const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const chalk = require('chalk');
const pkg = require('./package.json');

const devProxy = require('./webpack.dev.proxy');

const port = process.env.PORT || 10000;
const NODE_ENV = process.env.NODE_ENV || 'development';
const env = { development: 'test', production: 'prd' }[NODE_ENV];

const isDev = env === 'test'; // build mode: development

const resolve = (pn) => path.resolve(__dirname, `${pn}`);

const publicPath = isDev ? '/' : `https://static.zuifuli.com/test/mkt/icare-zfl-febase/bpmn-test`; // '<%= publicPath %>/';

const cssLoader = isDev
  ? 'style-loader'
  : {
      loader: MiniCssExtractPlugin.loader,
      options: {
        publicPath,
      },
    };

const config = {
  mode: isDev ? 'development' : 'production',
  bail: !isDev,
  entry: {
    entry: ['./src/entry/index.jsx'],
  },
  output: {
    path: resolve('assets'),
    chunkFilename: `[name].[contenthash:6].js`,
    filename: isDev ? '[name].js' : `[name].[contenthash:6].js`,
    publicPath,
  },
  devtool: isDev ? 'cheap-module-source-map' : false,
  target: 'web',
  module: {
    rules: [
      {
        test: /\.[j|t]s(x)?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            cacheDirectory: true,
          },
        },
      },
      {
        test: /\.(sa|sc)ss$/,
        // exclude: /node_modules/,
        use: [
          cssLoader,
          { loader: 'css-loader', options: { importLoaders: 2 } },
          'postcss-loader',
          'sass-loader',
        ],
      },
      {
        test: /\.css$/i,
        // exclude: /node_modules/,
        use: [cssLoader, { loader: 'css-loader', options: { importLoaders: 2 } }, 'postcss-loader'],
      },
      {
        test: /\.(png|jpg|gif|jpeg|svg)$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: isDev ? 1 : 10000,
            name: '[name].[contenthash:6].[ext]',
          },
        },
      },
      {
        test: /\.(ttf|otf|woff|woff2|eot)$/,
        use: {
          loader: 'url-loader',
          options: {
            name: './fonts/[name].[ext]',
            limit: 8192,
          },
        },
      },
    ],
  },
  resolve: {
    extensions: ['.js', '.jsx', '.json', '.scss'],
    alias: {
      '~': path.resolve(__dirname, './src'),
      'bpmn-js': path.resolve(__dirname, '../node_modules/bpmn-js'),
      'bpmn-js-token-simulation': path.resolve(__dirname, '../node_modules/bpmn-js-token-simulation'),
      'diagram-js-minimap': path.resolve(__dirname, '../node_modules/diagram-js-minimap'),
      'bpmn-js-properties-panel': path.resolve(__dirname, '../node_modules/bpmn-js-properties-panel'),
    },
    modules: [resolve('src'), 'node_modules'],
  },
  optimization: {
    splitChunks: {
      name: false,
      cacheGroups: {
        common: {
          name: 'common',
          chunks: 'all',
          minChunks: 2,
        },
        vendor: {
          name: 'vendor',
          test: /[\\/]node_modules[\\/]/,
          chunks: 'all',
          priority: 10,
        },
      },
    },
    runtimeChunk: {
      name: 'runtime',
    },
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: `[name].[contenthash:6].css`,
      chunkFilename: `[name].[contenthash:6].css`,
    }),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: resolve('index.html'),
      inject: 'body',
      // templateContent: ({ htmlWebpackPlugin }) => getHtmlTpl(isDev, htmlWebpackPlugin),
      // inject: false,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true,
      },
    }),
    new webpack.DefinePlugin({
      __client__: true,
      __dev__: isDev,
      __local_proxy__: !!devProxy,
    }),
    new webpack.ids.HashedModuleIdsPlugin({
      hashDigestLength: 20,
    }),
    new webpack.ProgressPlugin({
      // entries: true,
      modules: true,
      modulesCount: 100,
      profile: true,
      handler: (percent, message, ...args) => {
        // const num = `${percent}`.match(/\d\.\d{0,3}/);
        if (percent == 0) return console.log('\n\n');
        const num = Math.floor(percent * 100);
        const text =
          chalk.blue('>>>>>') +
          chalk.green(`${num}%`) +
          chalk.blue(`: ${message}【${args[0] || ''} - ${args[1] || ''}】`);

        if (process.stderr.clearLine && process.stderr.cursorTo && process.stderr.write) {
          process.stderr.clearLine();
          process.stderr.cursorTo(0);
          process.stderr.write(text);
        } else {
          console.log(text);
        }
        if (percent >= 100) return console.log('\n\n\n');
      },
    }),
  ],
};

if (isDev) {
  config.plugins.push(
    new ReactRefreshWebpackPlugin({
      overlay: false,
    })
  );

  config.stats = 'errors-warnings';

  // 默认支持使用charles/whistle代理 (本机ip不可访问)
  // 如果需要连接本机ip联调，配置 host: '0.0.0.0',useLocalIp: true (此时charles代理hmr不可用，whistle不受影响)
  config.devServer = {
    disableHostCheck: true,
    contentBase: resolve('static'),
    host: '127.0.0.1',
    useLocalIp: false,
    // host: '0.0.0.0',
    // useLocalIp: true,
    port,
    hot: true,
    inline: true,
    headers: { 'Access-Control-Allow-Origin': '*' },
    historyApiFallback: {
      rewrites: [{ from: /^\/$/, to: '/index.html' }],
    },
    proxy: {
      // 如果是 /api 打头，则访问地址如下
      '/api': devProxy,
    },
    // writeToDisk: true,
  };

  // IP访问
  if (process.env.IP) {
    config.devServer.useLocalIp = true;
    config.devServer.host = '0.0.0.0';
  }

  console.log(chalk.green(`开发地址:http://localhost:${port}`));
} else {
  config.stats = 'errors-only';
  config.plugins.push(
    new OptimizeCSSAssetsPlugin({
      cssProcessorOptions: {
        discardComments: { removeAll: true },
        // 避免 cssnano 重新计算 z-index
        safe: true,
        // cssnano 集成了autoprefixer的功能
        // 会使用到autoprefixer进行无关前缀的清理
        // 关闭autoprefixer功能
        // 使用postcss的autoprefixer功能
        autoprefixer: false,
      },
    })
  );

  if (process.env.ANALYZER) {
    config.plugins.push(
      new (require('webpack-bundle-analyzer').BundleAnalyzerPlugin)({
        openAnalyzer: true,
        analyzerMode: 'static',
        reportFilename: resolve('report.html'),
      })
    );
  }
}

module.exports = config;
